package com.power.project.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.power.base.service.impl.BaseServiceImpl;
import com.power.common.exception.CustomBizException;
import com.power.common.util.NanoidUtil;
import com.power.project.dao.P_projectDao;
import com.power.project.model.P_project;
import com.power.project.model.P_projectuser;
import com.power.project.model.Ww_user;
import com.power.project.model.bo.ProjectSaveBO;
import com.power.project.model.bo.ProjectUserSaveBO;
import com.power.project.model.pageInfo.P_projectPageInfo;
import com.power.project.model.pageInfo.P_projectuserPageInfo;
import com.power.project.model.vo.ProjectVO;
import com.power.project.model.vo.UserBaseVO;
import com.power.project.service.P_projectService;
import com.power.project.service.P_projectuserService;
import com.power.project.service.Ww_userService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目业务层实现
 */
@Service
public class P_projectServiceImpl extends BaseServiceImpl implements P_projectService {

    @Autowired
    private P_projectDao dao;

    @Autowired
    private Ww_userService ww_userService;

    @Autowired
    private P_projectuserService p_projectuserService;

    @Override
    public P_project getById(Serializable id) {
        return dao.findById(id).orElse(null);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdate(P_project p_project) {
        // save 如果数据库不存在这条数据，就会执行保存（即将这条数据插入到数据库）；如果数据库存在这条数据，就会根据主键去更新这条数据
        if (p_project.getPrimaryKey() != null) {
            P_project p_projectfDb = dao.findById(p_project.getPrimaryKey()).orElse(null);
            if (p_projectfDb != null) {
                BeanUtils.copyProperties(p_project, p_projectfDb);
                dao.save(p_projectfDb);
                return;
            }
        }
        dao.save(p_project);
    }

    @Override
    public void removeById(Serializable id) {
        // dao.deleteById(id);
        // 逻辑删除
        dao.removeById(id);
    }


    @Override
    public Page<ProjectVO> findAll(P_projectPageInfo pageInfo) {

        if (CollUtil.isNotEmpty(pageInfo.getWwuserids())) {
            List<Integer> pid = p_projectuserService.getProjectIdsByUserIds(pageInfo.getWwuserids());
            if (pid == null || pid.isEmpty()) {
                return new PageImpl<>(new ArrayList<>(), PageRequest.of(pageInfo.getPageNumber() <= 1 ? 0 : pageInfo.getPageNumber() - 1, pageInfo.getPageSize()), 0);
            } else {
                pageInfo.setF_ids(pid);
            }
        }

        //分页的定义
        Pageable pageable = PageRequest.of(pageInfo.getPageNumber() <= 1 ? 0 : pageInfo.getPageNumber() - 1, pageInfo.getPageSize());
        Page<P_project> result = dao.findPage(pageInfo, pageable);

        List<P_project> p_projectList = result.getContent();

        if (p_projectList == null || p_projectList.size() == 0) {
            return new PageImpl<>(new ArrayList<>(), pageable, result.getSize());
        }

        //项目关联用户 List
        Map<Integer, List<P_projectuser>> upmap;
        //项目id List
        List<Integer> pIdList = new ArrayList<>();
        // userInfoMap
        List<ProjectVO> projectVOList = p_projectList.stream().map((pProject -> {
                    ProjectVO projectVO = new ProjectVO();
                    BeanUtils.copyProperties(pProject, projectVO);
                    //如果有内容
                    if (StringUtils.hasText(pProject.getMgruserids())) {
                        String[] split = pProject.getMgruserids().split(",");
                        List<String> mgruserIdList = new ArrayList<>(Arrays.asList(split));
                        projectVO.setMgruserIdList(mgruserIdList);
                    }
                    pIdList.add(projectVO.getId());
                    return projectVO;
                })
        ).collect(Collectors.toList());
        //找出全部关联员工-->(projectid,user)
        upmap = findpuByPidList(pIdList);
        if (CollUtil.isEmpty(upmap) || CollUtil.isEmpty(projectVOList)) {
            return new PageImpl<>(projectVOList, pageable, result.getTotalElements());
        } else {
            //封装员工进数据
            Map<Integer, List<P_projectuser>> finalUpmap = upmap;
            projectVOList.forEach((pVO) -> {
                List<P_projectuser> mgar = new ArrayList<>();
                List<P_projectuser> user = new ArrayList<>();
                pVO.setPUserList(new HashMap<>(2));
                if (CollUtil.isEmpty(pVO.getMgruserIdList())) {
                    user = finalUpmap.get(pVO.getId());
                } else if (upmap != null && pVO.getMgruserIdList().size() == upmap.size()) {
                    mgar = finalUpmap.get(pVO.getId());
                } else if (upmap != null) {
                    if (CollUtil.isNotEmpty(finalUpmap.get(pVO.getId()))) {
                        List<P_projectuser> pProjectusers = finalUpmap.get(pVO.getId());
                        if (CollUtil.isNotEmpty(pProjectusers)) {
                            List<P_projectuser> finalUser = user;
                            List<P_projectuser> finalMgar = mgar;
                            pProjectusers.forEach((item) -> {
                                        if (pVO.getMgruserIdList().contains(item.getWwuserid())) {
                                            finalMgar.add(item);
                                        } else {
                                            finalUser.add(item);
                                        }
                                    }
                            );
                        }
                    }
                }
                pVO.getPUserList().put("mgar", mgar);
                pVO.getPUserList().put("user", user);
            });
        }
        return new PageImpl<>(projectVOList, pageable, result.getTotalElements());
    }

    private Map<Integer, List<P_projectuser>> findpuByPidList(List<Integer> pIdList) {
        List<P_projectuser> puList = this.p_projectuserService.findByProjectidIn(pIdList);
        if (CollUtil.isNotEmpty(puList)) {
            Map<Integer, List<P_projectuser>> groupedByProjectId = puList.stream()
                    .collect(Collectors.groupingBy(P_projectuser::getProjectid));
            return groupedByProjectId;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByIds(List<Integer> ids) {
        dao.removeByIds(ids);
    }


    @Override
    public void saveAll(List<P_project> list) {
        dao.saveAll(list);
    }

    @Override
    public Page<UserBaseVO> queryUsersByPid(P_projectuserPageInfo pageInfo) {

        List<UserBaseVO> userVOList = dao.queryUsersByPid(pageInfo);
        //分页的定义
        Pageable pageable = PageRequest.of(pageInfo.getPageNumber() <= 1 ? 0 : pageInfo.getPageNumber() - 1, pageInfo.getPageSize());

        return new PageImpl<>(userVOList, pageable, pageInfo.getAllcount());
    }

    @Override
    @Transactional
    public void addProjectuser(ProjectUserSaveBO puSaveBo) {
        //查询是否已经关联本项目
        P_project p_project = dao.getById(puSaveBo.getProjectId());
        Assert.isTrue(puSaveBo.getTenantid().equals(p_project.getTenantid()), "不可以操作非本租户的信息");
        // 校验是否是项目租户
        List<Ww_user> userList = ww_userService.findByTenantidAndUseridIn(puSaveBo.getTenantid(), puSaveBo.getUserIds());
        if (userList == null || userList.size() != puSaveBo.getUserIds().size()) {
            throw new CustomBizException("存在用户不在本租户的添加");
        }
        List<P_projectuser> puList = p_projectuserService.findByProjectidAndWwuseridIn(puSaveBo.getProjectId(), puSaveBo.getUserIds());
        if (CollUtil.isNotEmpty(puList)) {
            throw new CustomBizException("存在重复添加");
        }
        //组装数据
        List<P_projectuser> newPuList = userList.stream().map((user) -> {
            P_projectuser pProjectuser = new P_projectuser();
            pProjectuser.setWwuserid(user.getUserid());
            pProjectuser.setWwusername(user.getName());
            pProjectuser.setProjectid(puSaveBo.getProjectId());
            pProjectuser.setIsdefault(3201);
            return pProjectuser;
        }).collect(Collectors.toList());

        p_projectuserService.saveAll(newPuList);
    }

    @Override
    public void save(ProjectSaveBO saveBO) {
        if (saveBO.getId() != null) {
            P_project p_project = dao.getById(saveBO.getId());
            Assert.isTrue(saveBO.getTenantid().equals(p_project.getTenantid()), "不可以修改其他租户id");
            if (StringUtils.hasText(saveBO.getProjectname())) {
                p_project.setProjectname(saveBO.getProjectname());
            }
            if (StringUtils.hasText(saveBO.getClientcompany())) {
                p_project.setClientcompany(saveBO.getClientcompany());
            }
            if (ObjectUtil.isNotEmpty(saveBO.getFinished())) {
                p_project.setFinished(saveBO.getFinished());
            }
            dao.save(p_project);
        } else {
            if (StringUtils.hasText(saveBO.getProjectcode())) {
                Long count = dao.countByProjectcode(saveBO.getProjectcode());
                if (count == 0) {
                    throw new CustomBizException("项目的唯一标识错误");
                }
                P_project pProject = new P_project();
                pProject.setProjectname(saveBO.getProjectname());
                pProject.setClientcompany(saveBO.getClientcompany());
                pProject.setDeleted(0);
                pProject.setFinished(3201);
                if (CollUtil.isNotEmpty(saveBO.getMgruserids())) {
                    String Mgruserids = String.join(",", saveBO.getMgruserids());
                    pProject.setMgruserids(Mgruserids);
                }
                pProject.setVersion(count.intValue());
                pProject.setProjectcode(saveBO.getProjectcode());
                pProject.setTenantid(saveBO.getTenantid());
                dao.save(pProject);
            } else {
                P_project pProject = new P_project();
                pProject.setProjectname(saveBO.getProjectname());
                pProject.setClientcompany(saveBO.getClientcompany());
                pProject.setDeleted(0);
                pProject.setFinished(3201);
                if (CollUtil.isNotEmpty(saveBO.getMgruserids())) {
                    String Mgruserids = String.join(",", saveBO.getMgruserids());
                    pProject.setMgruserids(Mgruserids);
                }
                pProject.setVersion(0);
                pProject.setProjectcode(NanoidUtil.randomNanoId());
                pProject.setTenantid(saveBO.getTenantid());
                dao.save(pProject);
            }
        }

    }

    @Override
    public void removeProjectuser(ProjectUserSaveBO puSaveBo) {
        // 校验是否是本人项目组
        P_project p_project = dao.getById(puSaveBo.getProjectId());
        if (ObjectUtil.isEmpty(p_project)) {
            throw new CustomBizException("不是存在该项目");
        }
        Assert.isTrue(puSaveBo.getTenantid().equals(p_project.getTenantid()), "不可以操作其他租户数据");
        p_projectuserService.deleteByProjectIdAndWwuserids(puSaveBo.getProjectId(), puSaveBo.getUserIds());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveProjectuser(ProjectUserSaveBO puSaveBo) {
        // 校验是否是本人项目组
        P_project p_project = dao.getById(puSaveBo.getProjectId());
        if (ObjectUtil.isEmpty(p_project)) {
            throw new CustomBizException("不是存在该项目");
        }
        if (!puSaveBo.checkMGRInUsers(puSaveBo.getUserIds(), puSaveBo.getMgruserids())) {
            throw new CustomBizException("管理者必须是项目参与人员");
        }

        //判断是否修改了管理人员
        String mgarIdsBO = String.join(",", puSaveBo.getMgruserids());
        if (!mgarIdsBO.equals(p_project.getMgruserids())) {
            p_project.setMgruserids(mgarIdsBO);
            dao.updateMgruseridsById(puSaveBo.getProjectId(), mgarIdsBO);
        }
        //  得出双放的 set
        Set<String> puSet = new HashSet<>();
        List<String> useridsByProjectId = p_projectuserService.getUseridsByProjectId(puSaveBo.getProjectId());
        if (CollUtil.isNotEmpty(useridsByProjectId)) {
            puSet = new HashSet<>(useridsByProjectId);
        }
        Set<String> puSaveSet = new HashSet<>(puSaveBo.getUserIds());
        // 得到需要删除的set（即 puSet 中有但 puSaveSet 中没有的元素）
        Set<String> toDeleteSet = new HashSet<>(puSet);
        toDeleteSet.removeAll(puSaveSet);
        // 得到需要添加的set（即 puSaveSet 中有但 puSet 中没有的元素）
        Set<String> toAddSet = new HashSet<>(puSaveSet);
        toAddSet.removeAll(puSet);

        if (CollUtil.isNotEmpty(toDeleteSet)) {
            p_projectuserService.deleteByProjectIdAndWwuserids(puSaveBo.getProjectId(), new ArrayList<>(toDeleteSet));
        }
        if (CollUtil.isNotEmpty(toAddSet)) {
            List<Ww_user> ww_userList = ww_userService.findByUseridIn(new ArrayList<>(toAddSet));
            if (CollUtil.isNotEmpty(ww_userList)) {
                List<P_projectuser> p_projectuserList = ww_userList.stream().map((user) -> {
                    P_projectuser pProjectuser = new P_projectuser();
                    pProjectuser.setWwuserid(user.getUserid());
                    pProjectuser.setWwusername(user.getName());
                    pProjectuser.setProjectid(puSaveBo.getProjectId());
                    pProjectuser.setIsdefault(3201);
                    return pProjectuser;
                }).collect(Collectors.toList());
                p_projectuserService.saveAll(p_projectuserList);
            }
        }
    }
}
